package com.flow.framework.base.controller;

import com.flow.framework.base.constant.FrameworkBaseConstant;
import com.flow.framework.common.health.ServiceHealthCheckCode;
import com.flow.framework.common.pojo.vo.system.ServiceHealthVo;
import com.flow.framework.common.service.system.health.IHealthCheckService;
import com.flow.framework.common.util.verify.VerifyUtil;
import com.flow.framework.core.system.helper.SystemHealthHelper;
import com.flow.framework.core.response.Response;
import com.flow.framework.core.system.listener.lifecycle.ISystemLifecycleListener;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * 系统敏感操作
 *
 * @author luoguopiao
 * @version 0.0.1
 * @date 2022/12/10
 */
@RestController
@RequestMapping("/")
@Slf4j
@RequiredArgsConstructor
public class SystemOpsController {

    private final List<ISystemLifecycleListener> systemLifecycleListeners;

    private final List<IHealthCheckService> healthCheckServices;

    /**
     * 健康检查接口
     *
     * @return 系统监控指标
     */
    @GetMapping(path = FrameworkBaseConstant.NO_CONTEXT_PATH_HEALTH_CHECK_URI)
    public Response<List<ServiceHealthVo>> healthCheck() {
        List<ServiceHealthVo> finalServiceHealthVos = new ArrayList<>();
        if (VerifyUtil.isEmpty(healthCheckServices)) {
            return Response.success(finalServiceHealthVos);
        }

        List<String> unhealthyServices = new ArrayList<>();
        for (IHealthCheckService healthCheckService : healthCheckServices) {
            String clazzName = healthCheckService.getClass().getSimpleName();
            try {
                List<ServiceHealthVo> serviceHealthVos = healthCheckService.check();
                if (null == serviceHealthVos) {
                    unhealthyServices.add(clazzName);
                    continue;
                }
                finalServiceHealthVos.addAll(serviceHealthVos);
            } catch (Exception e) {
                log.error("check health error. clazz name : {}", clazzName, e);
                unhealthyServices.add(clazzName);
            }
        }
        if (!VerifyUtil.isEmpty(unhealthyServices)) {
            ServiceHealthVo serviceHealthVo = SystemHealthHelper.unhealthy(ServiceHealthCheckCode.SERVICE_HEALTH_CHECK_CODE,
                    null, unhealthyServices);
            finalServiceHealthVos.add(serviceHealthVo);
        }
        return Response.success(finalServiceHealthVos);
    }

    /**
     * 系统在关闭前的预处理接口
     *
     * @return Response
     */
    @PutMapping(path = FrameworkBaseConstant.NO_CONTEXT_PATH_BEFORE_SHUTDOWN_URI)
    public Response beforeShutdown() {
        if (VerifyUtil.isEmpty(systemLifecycleListeners)) {
            return Response.success();
        }
        systemLifecycleListeners.forEach(ISystemLifecycleListener::beforeShutdown);
        return Response.success();
    }

    /**
     * 手动上线接口
     *
     * @return Response
     */
    @PutMapping(path = FrameworkBaseConstant.NO_CONTEXT_PATH_MANUAL_ONLINE_URI)
    public Response manualOnline() {
        if (VerifyUtil.isEmpty(systemLifecycleListeners)) {
            return Response.success();
        }
        systemLifecycleListeners.forEach(ISystemLifecycleListener::manualOnline);
        return Response.success();
    }
}
